package com.qianfeng.smartplatform.service.impl;

//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼                  BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  
//  


import com.github.pagehelper.PageInfo;
import com.qianfeng.smartplatform.cache.CategoriesCache;
import com.qianfeng.smartplatform.constants.ResultCode;
import com.qianfeng.smartplatform.constants.ResultEnum;
import com.qianfeng.smartplatform.constants.StatusConstants;
import com.qianfeng.smartplatform.event.CategoryChangeEvent;
import com.qianfeng.smartplatform.exceptions.AddErrorException;
import com.qianfeng.smartplatform.exceptions.DeleteErrorException;
import com.qianfeng.smartplatform.exceptions.QueryDataException;
import com.qianfeng.smartplatform.exceptions.UpdateErrorException;
import com.qianfeng.smartplatform.mapper.CategoryMapper;
import com.qianfeng.smartplatform.pojo.Category;
import com.qianfeng.smartplatform.pojo.CategoryExample;
import com.qianfeng.smartplatform.pojo.CheckType;
import com.qianfeng.smartplatform.security.BaseUser;
import com.qianfeng.smartplatform.service.CategoryService;
import com.qianfeng.smartplatform.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created by Jackiechan on 2021/12/20/11:23
 *
 * @author Jackiechan
 * @version 1.0
 * @since 1.0
 */
@Service
@Transactional
public class CategoryServiceImpl implements CategoryService {

    private CategoryMapper categoryMapper;


    private CategoriesCache categoriesCache;//缓存对象

    @Autowired
    public void setCategoriesCache(CategoriesCache categoriesCache) {
        this.categoriesCache = categoriesCache;

    }

    private ApplicationContext context;

    @Autowired
    public void setContext(ApplicationContext context) {
        this.context = context;
    }

    @Autowired
    public void setCategoryMapper(CategoryMapper categoryMapper) {
        this.categoryMapper = categoryMapper;
    }

    @Override
    public void addCategory(Category category) {
        //获取当前登录的用户
        BaseUser baseUser = SecurityUtils.getUser();
        Assert.notNull(baseUser,()->{
            throw new AddErrorException(ResultEnum.NOT_LOGIN);
        });
        //设置创建者为当前登录的用户
        category.setCreateBy(baseUser.getUsername());
        //断言数据肯定不为空,否则抛出异常
        Assert.isTrue(category != null && !category.isEmpty(CheckType.ADD), () -> {
            throw new AddErrorException(ResultEnum.NULL_DATA);
        });


        //按照名字查询当前分类是不是已经存在
        Category categoryByName = getCategoryByName(category.getCategoryName());
        //如果存在,就抛出异常
        Assert.isNull(categoryByName, () -> {
            throw new AddErrorException(ResultEnum.DATA_ALLREADY_EXIST);
        });
        category.setCreateTime(new Date());

        categoryMapper.insertSelective(category);//插入数据
        context.publishEvent(new CategoryChangeEvent());//发布更新事件
    }

    @Override
    public void updateCategory(Category category) {
        //获取当前登录的用户
        BaseUser baseUser = SecurityUtils.getUser();
        Assert.notNull(baseUser,()->{
            throw new AddErrorException(ResultEnum.NOT_LOGIN);
        });
        //设置更新者为当前登录的用户
        category.setUpdateBy(baseUser.getUsername());
        //没有传递对象,或者没有传递主键 或者传递的主键是空的
        Assert.isTrue(category != null &&(!ObjectUtils.isEmpty(category.getcId())&&category.getcId()>0), () -> {
            throw new UpdateErrorException(ResultEnum.ID_NULL);
        });
        //更新的时候必须传递的数据
        Assert.isTrue(category != null && !category.isEmpty(CheckType.UPDATE), () -> {
            throw new UpdateErrorException(ResultEnum.NULL_DATA);
        });
        category.setCreateTime(null);//不允许更新创建时间
        category.setCreateBy(null);//不允许更新创建者
        category.setUpdateTime(new Date());
        int result = categoryMapper.updateByPrimaryKeySelective(category);//更新数据

        Assert.isTrue(result>0,()->{//如果返回的结果不大于0则代表更新失败,但是没有抛出异常,只能说是条件不成立,那就是数据不存在
            throw new UpdateErrorException(ResultEnum.DATA_NOT_EXIST);
        });
        context.publishEvent(new CategoryChangeEvent());//发布更新事件
    }

    @Override
    public Category getCategoryById(Integer id) {
        Assert.isTrue(!ObjectUtils.isEmpty(id)&&id>0, () -> {
            throw new UpdateErrorException(ResultEnum.ID_NULL);
        });
        Category category = categoriesCache.get(id);
        return category;
        //  return categoryMapper.selectByPrimaryKey(id);
    }

    @Override
    public Category getCategoryByName(String categoryName) {
        //按照名字查询必须传递名字
        Assert.hasText(categoryName, () -> {
            throw new QueryDataException(ResultEnum.NULL_DATA);
        });
        return categoryMapper.selectByName(categoryName);
    }

    @Override
    public PageInfo<Category> getAllCategoriesByPage(int pageNum, int pageSize, String categoryname, Short status) {
//        PageHelper.startPage(pageNum, pageSize);
//        CategoryExample example = new CategoryExample();
//        CategoryExample.Criteria criteria = example.createCriteria();
//        if (StringUtils.hasText(categoryname)) {
//            criteria.andCategoryNameEqualTo(categoryname);
//        }
//        if (!ObjectUtils.isEmpty(status)) {
//            criteria.andStatusEqualTo(status);
//        }
//        List<Category> categoryList = categoryMapper.selectByExample(example);
        List<Category> allData = categoriesCache.getAllData();
        Stream<Category> categoryStream = allData.stream();
        //如果设置了名字,按照名字过滤,可以使用contains来判断部分,如果要完整匹配可以equals
        if (StringUtils.hasText(categoryname)) {
            categoryStream= categoryStream.filter(category -> category.getCategoryName().contains(categoryname));
        }
        //如果设置了状态,按照状态过滤
        if (!ObjectUtils.isEmpty(status)) {
            categoryStream= categoryStream.filter(category -> category.getStatus() == status);
        }
        List<Category> list = categoryStream.collect(Collectors.toList());//先收集一下符合条件的数据,用于后面进行总条数判断
        //对符合条件的数据按照分页过滤数据
        List<Category> categoryList = list.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        PageInfo<Category> pageInfo = new PageInfo<>(categoryList);
        pageInfo.setTotal(list.size());
        return pageInfo;
    }

    @Override
    public List<Category> getAllCategories(Short status) {
        if (ObjectUtils.isEmpty(status)) {
            return categoriesCache.getAllData();//从缓存中查询
        }
        Assert.isTrue(status>=StatusConstants.DISABLE,()->{
            throw new QueryDataException("状态不符合要求",ResultCode.DATA_NOT_ALLOWED);
        });
        //从缓存中获取类型匹配的数据
        return categoriesCache.getAllData().stream()
                .filter(category -> category.getStatus() == status)//比较类型
                .collect(Collectors.toList());//放到新的集合
//        return categoryMapper.selectByExample(new CategoryExample());
    }

    @Override
    public void deleteCategories(List<Integer> ids) {
        //获取当前登录的用户
        BaseUser baseUser = SecurityUtils.getUser();
        Assert.notNull(baseUser,()->{
            throw new AddErrorException(ResultEnum.NOT_LOGIN);
        });
        //设置更新者为当前登录的用户
        Assert.notEmpty(ids,()->{
            throw new DeleteErrorException(ResultEnum.ID_NULL);
        });
        Category category = new Category();
        //设置当前的登陆用户
        category.setUpdateBy(baseUser.getUsername());
        //设置更新时间
        category.setUpdateTime(new Date());
        category.setStatus(StatusConstants.DISABLE);//设置为无效
        CategoryExample example = new CategoryExample();
        example.createCriteria().andCIdIn(ids);
        //删除数据之前应该先判断分类有没有数据,有的话不能删除,此处没执行相关业务
        int result = categoryMapper.updateByExampleSelective(category,example);
        //    int result = categoryMapper.deleteByExample(example);

        Assert.isTrue(result>0,()->{//要删除的数据不存在
            throw new DeleteErrorException(ResultEnum.DATA_NOT_EXIST);
        });
        context.publishEvent(new CategoryChangeEvent());//发布更新事件
    }
}
